{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a8b892c8",
   "metadata": {},
   "source": [
    "Printed and electronic copies of *Modeling and Simulation in Python* are available from [No Starch Press](https://nostarch.com/modeling-and-simulation-python) and [Bookshop.org](https://bookshop.org/p/books/modeling-and-simulation-in-python-allen-b-downey/17836697?ean=9781718502161) and [Amazon](https://amzn.to/3y9UxNb)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dense-storm",
   "metadata": {},
   "source": [
    "# Case Studies Part 1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "imported-table",
   "metadata": {
    "tags": []
   },
   "source": [
    "*Modeling and Simulation in Python*\n",
    "\n",
    "Copyright 2021 Allen Downey\n",
    "\n",
    "License: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "formal-context",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "# download modsim.py if necessary\n",
    "\n",
    "from os.path import basename, exists\n",
    "\n",
    "def download(url):\n",
    "    filename = basename(url)\n",
    "    if not exists(filename):\n",
    "        from urllib.request import urlretrieve\n",
    "        local, _ = urlretrieve(url, filename)\n",
    "        print('Downloaded ' + local)\n",
    "    \n",
    "download('https://raw.githubusercontent.com/AllenDowney/' +\n",
    "         'ModSimPy/master/modsim.py')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "progressive-typing",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "# import functions from modsim\n",
    "\n",
    "from modsim import *"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "thirty-medication",
   "metadata": {},
   "source": [
    "This chapter presents case studies where you can apply the tools we have learned so far to problems involving population growth, queueing systems, and tree growth. \n",
    "\n",
    "This chapter is available as a Jupyter notebook where you can read the text, run the code, and work on the exercises. \n",
    "Click here to access the notebooks: <https://allendowney.github.io/ModSimPy/>."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "industrial-mercy",
   "metadata": {},
   "source": [
    "## Historical World Population\n",
    "\n",
    "The Wikipedia page about world population growth includes estimates for world population from 12,000 years ago to the present (see <https://en.wikipedia.org/wiki/World_population_estimates.html>)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "weekly-class",
   "metadata": {
    "tags": []
   },
   "source": [
    "The following cells download an archived version of this page and read the data into a Pandas `DataFrame`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "usual-penguin",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "download('https://raw.githubusercontent.com/AllenDowney/' +\n",
    "         'ModSimPy/master/data/World_population_estimates.html')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "thick-lincoln",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "from pandas import read_html\n",
    "\n",
    "filename = 'World_population_estimates.html'\n",
    "tables = read_html(filename, header=0, index_col=0, decimal='M')\n",
    "len(tables)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "conscious-orange",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "table1 = tables[1]\n",
    "table1.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "hungry-monster",
   "metadata": {
    "tags": []
   },
   "source": [
    "Some of the values are null because not all researchers provide estimates for the same dates.\n",
    "\n",
    "Again, we'll replace the long column names with more convenient abbreviations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "thick-blanket",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "table1.columns = ['PRB', 'UN', 'Maddison', 'HYDE', 'Tanton', \n",
    "                  'Biraben', 'McEvedy & Jones', 'Thomlinson', 'Durand', 'Clark']"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "substantial-implement",
   "metadata": {
    "tags": []
   },
   "source": [
    "Some of the estimates are in a form Pandas doesn't recognize as numbers, but we can coerce them to be numeric."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "ranking-prescription",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "for col in table1.columns:\n",
    "    table1[col] = pd.to_numeric(table1[col], errors='coerce')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "amazing-difference",
   "metadata": {
    "tags": []
   },
   "source": [
    "Here are the results.  Notice that we are working in millions now, not billions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "metallic-offense",
   "metadata": {
    "scrolled": false,
    "tags": []
   },
   "outputs": [],
   "source": [
    "table1.plot()\n",
    "decorate(xlim=[-10000, 2000], xlabel='Year', \n",
    "         ylabel='World population (millions)',\n",
    "         title='Prehistoric population estimates')\n",
    "plt.legend(fontsize='small');"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "human-conservation",
   "metadata": {
    "tags": []
   },
   "source": [
    "We can use `xlim` to zoom in on everything after Year 0."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "conventional-nudist",
   "metadata": {},
   "source": [
    "The following figure shows the estimates of several research groups from 1 CE to the near present."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "solar-action",
   "metadata": {},
   "outputs": [],
   "source": [
    "table1.plot()\n",
    "decorate(xlim=[0, 2000], xlabel='Year', \n",
    "         ylabel='World population (millions)',\n",
    "         title='CE population estimates')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "wanted-fantasy",
   "metadata": {},
   "source": [
    "See if you can find a model that fits these estimates.\n",
    "How well does your best model predict actual population growth from 1940 to the present?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "rural-express",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "tables = read_html(filename, header=0, index_col=0, decimal='M')\n",
    "table2 = tables[2]\n",
    "table2.columns = ['census', 'prb', 'un', 'maddison', \n",
    "                  'hyde', 'tanton', 'biraben', 'mj', \n",
    "                  'thomlinson', 'durand', 'clark']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "preceding-sheep",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "un = table2.un / 1e9\n",
    "census = table2.census / 1e9"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "together-jackson",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Solution goes here"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "simple-verse",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# Solution goes here"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ruled-spain",
   "metadata": {},
   "source": [
    "## One Queue Or Two?\n",
    "\n",
    "This case study is related to *queueing theory*, which is the study of systems that involve waiting in lines, also known as \"queues\".\n",
    "\n",
    "Suppose you are designing the checkout area for a new store. There is\n",
    "enough room in the store for two checkout counters and a waiting area\n",
    "for customers. You can make two lines, one for each counter, or one line that feeds both counters.\n",
    "\n",
    "In theory, you might expect a single line to be better, but it has some practical drawbacks: in order to maintain a single line, you might have to install barriers, and customers might be put off by what seems to be a longer line, even if it moves faster.\n",
    "\n",
    "So you'd like to check whether the single line is really better and by\n",
    "how much. Simulation can help answer this question.\n",
    "\n",
    "This figure shows the three scenarios we'll consider:\n",
    "\n",
    "![One queue, one server (left), one queue, two servers (middle), two\n",
    "queues, two servers (right).](https://github.com/AllenDowney/ModSim/raw/main/figs/queue.png)\n",
    "\n",
    "*One queue, one server (left), one queue, two servers (middle), two\n",
    "queues, two servers (right).*\n",
    "\n",
    "As we did in the bike share model, we'll divide time into discrete time steps of one minute.\n",
    "And we'll assume that a customer is equally likely to arrive during any time step. \n",
    "I'll denote this probability using the Greek letter lambda, $\\lambda$, or the variable name `lam`. The value of $\\lambda$ probably varies from day to day, so we'll have to consider a range of possibilities.\n",
    "\n",
    "Based on data from other stores, you know that it takes 5 minutes for a customer to check out, on average. But checkout times are variable: most customers take less than 5 minutes, but some take substantially more. A simple way to model this variability is to assume that when a customer is checking out, they always have the same probability of finishing during the next time step, regardless of how long they have been checking out. I'll denote this probability using the Greek letter mu, $\\mu$, or the variable name `mu`.\n",
    "\n",
    "If we choose $\\mu=1/5$ per minute, the average time for each checkout\n",
    "will be 5 minutes, which is consistent with the data. Most people take less than 5 minutes, but a few take substantially longer, which is probably not a bad model of the distribution in real stores.\n",
    "\n",
    "Now we're ready to implement the model. In the repository for this book, you'll find a notebook called *queue.ipynb* that contains some code to get you started and instructions.\n",
    "You can download it from <https://github.com/AllenDowney/ModSimPy/raw/master/examples/queue.ipynb> or run it on Colab at <https://colab.research.google.com/github/AllenDowney/ModSimPy/blob/master/examples/queue.ipynb>.\n",
    "\n",
    "As always, you should practice incremental development: write no more\n",
    "than one or two lines of code at a time, and test as you go!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "forward-point",
   "metadata": {},
   "source": [
    "## Predicting Salmon Populations\n",
    "\n",
    "Each year the U.S. Atlantic Salmon Assessment Committee reports\n",
    "estimates of salmon populations in oceans and rivers in the northeastern United States. The reports are useful for monitoring changes in these populations, but they generally do not include predictions.\n",
    "\n",
    "The goal of this case study is to model year-to-year changes in\n",
    "population, evaluate how predictable these changes are, and estimate the probability that a particular population will increase or decrease in the next 10 years.\n",
    "\n",
    "As an example, I use data from the 2017 report, which provides population estimates for the Narraguagus and Sheepscot Rivers\n",
    "in Maine.\n",
    "\n",
    "In the repository for this book, you'll find a notebook called\n",
    "*salmon.ipynb* that contains this data and some code to get you started.\n",
    "You can download it from <https://github.com/AllenDowney/ModSimPy/raw/master/examples/salmon.ipynb> or run it on Colab at <https://colab.research.google.com/github/AllenDowney/ModSimPy/blob/master/examples/salmon.ipynb>.\n",
    "\n",
    "You should take my instructions as suggestions; if you want to try\n",
    "something different, please do!\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "limiting-moore",
   "metadata": {},
   "source": [
    "## Tree Growth\n",
    "\n",
    "This case study is based on \"Height-Age Curves for Planted Stands of\n",
    "Douglas Fir, with Adjustments for Density\", a working paper by\n",
    "Flewelling et al.\n",
    "It provides *site index curves*, which are curves that show the\n",
    "expected height of the tallest tree in a stand of Douglas fir as a\n",
    "function of age, for a stand where the trees are the same age.\n",
    "Depending on the quality of the site, the trees might grow more quickly or slowly. So each curve is identified by a *site index* that indicates the quality of the site.\n",
    "\n",
    "The goal of this case study is to explain the shape of these\n",
    "curves, that is, why trees grow the way they do.\n",
    "The answer I propose involves fractal dimensions, so you might find it interesting.\n",
    "\n",
    "In the repository for this book, you'll find a notebook called\n",
    "*trees.ipynb* that incrementally develops a model of tree growth and uses it to fit the data.\n",
    "You can download it from <https://github.com/AllenDowney/ModSimPy/raw/master/examples/trees.ipynb> or run it on Colab at <https://colab.research.google.com/github/AllenDowney/ModSimPy/blob/master/examples/trees.ipynb>.\n",
    "\n",
    "There are no exercises in this case study, but it is an example of what you can do with the tools we have so far and a preview of what you will be able to do with the tools in the next few chapters."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "australian-gregory",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "celltoolbar": "Tags",
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.16"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
